﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Common.Net.Utilities;
using System.Reflection;
using Common.Net.DesignByContract;

namespace ClearUnit.TestRunners.Results
{
    public sealed class AssemblyRunResult : TestRunResult
    {
        readonly Assembly _assembly;
        readonly IList<TypeRunResult> _allTypes;

        public IList<TypeRunResult> AllTypes
        {
            get { return _allTypes; }
        }

        public Assembly Assembly
        {
            get { return _assembly; }
        }

        public IEnumerable<MethodRunResult> AllMethods
        {
            get
            {
                foreach (var type in RunTypes)
                    foreach (var method in type.Methods)
                        yield return method;
            }
        }

        public IEnumerable<TypeRunResult.Run> RunTypes
        {
            get { return AllTypes.OfType<TypeRunResult.Run>(); }
        }

        public int RunCount
        {
            get { return RunTypes.Sum(t => t.MethodsRun.Count()); }
        }

        public int PassedCount
        {
            get { return RunTypes.Sum(t => t.PassedCount); }
        }

        public int SkippedCount
        {
            get { return RunTypes.Sum(t => t.SkippedCount); }
        }

        public int FailedCount
        {
            get { return RunTypes.Sum(t => t.FailedCount); }
        }

        public int TotalCount
        {
            get { return RunTypes.Sum(t => t.Methods.Count); }
        }

        public TimeSpan TotalLength
        {
            get { return RunTypes.Sum(t => t.TotalLength); }
        }

        public AssemblyRunResult(Assembly assembly, IList<TypeRunResult> types)
        {
            RequireArg.NotNull(() => assembly);

            _assembly = assembly;
            _allTypes = types.ToReadOnly();
        }

        public override string ShortDescription
        {
            get { return string.Format("Assembly {0} tests: {1} passed, {2} failed, {3} skipped. (Total {4} tests in {5} types, took {6})", _assembly.GetName().Name, PassedCount, FailedCount, SkippedCount, AllMethods.Count(), AllTypes.Count, TotalLength.Format()); }
        }
    }
}
